#pragma once

#include "file.h"
#include "stream.h"
#include "task.h"
#include <chrono>
#include <cstddef>
#include <span>
#include <sys/socket.h>
#include <unistd.h>
#include <utility>

namespace cobt {

inline thread_local size_t COBT_TCP_CONNECTIONS = 0;
class FileBuf {
public:
  FileBuf(std::chrono::milliseconds timeout = std::chrono::milliseconds::max())
      : m_file(-1), m_timeout(timeout) {}
  FileBuf(FileHandle &&file,
          std::chrono::milliseconds timeout = std::chrono::milliseconds::max())
      : m_file(std::move(file)), m_timeout(timeout) {
    if (m_file.get_fd() < 0) {
      return;
    }
  }
  FileBuf(FileBuf &&that) : m_file(std::move(that.m_file)){};
  FileBuf &operator=(FileBuf &&that) {
    m_file = std::move(that.m_file);
    return *this;
  };
  void set_handle(FileHandle &&file) { m_file = std::move(file); }

  Task<int> read(std::span<char> buf) { return m_file.read(buf, m_timeout); }
  Task<int> write(std::span<char> buf) { return m_file.write(buf, m_timeout); }
  ~FileBuf() {}
  void release() noexcept { m_file.release(); }
  const int get_fd() const noexcept { return m_file.get_fd(); }

private:
  FileHandle m_file;
  std::chrono::milliseconds m_timeout;
};

using FileStream = IOStream<FileBuf>;
} // namespace cobt
